home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH02 / WLOGIC / LOGICEV.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-12-30  |  22.2 KB  |  873 lines

  1. unit Logicev;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, ExtCtrls, VBXCtrl, Switch, StdCtrls, Buttons, TabNotBk,
  8.   Grids, About;
  9.  
  10. type
  11.   TLogicEval = class(TForm)
  12.     Screens: TTabbedNotebook;
  13.  
  14.     A: TBiSwitch;    { Input Switches on EXECUTE form.    }
  15.     B: TBiSwitch;
  16.     C: TBiSwitch;
  17.     D: TBiSwitch;
  18.  
  19.     W: TShape;        { Four LEDs on EXECUTE form.        }
  20.     X: TShape;
  21.     Y: TShape;
  22.     Z: TShape;
  23.     WLbl: TLabel;    {Labels on the LEDs.            }
  24.     XLbl: TLabel;
  25.     YLbl: TLabel;
  26.     ZLbl: TLabel;
  27.     E: TShape;
  28.     F: TShape;
  29.     G: TShape;
  30.     I: TShape;
  31.     J: TShape;
  32.     H: TShape;
  33.     K: TShape;
  34.     SevenSeg: TPanel;
  35.     ExecVariables: TStringGrid;
  36.  
  37.     EqnList: TListBox;        { List of equations on execute page.    }
  38.  
  39.     AInit: TGroupBox;        { "Buttons" on the INIT page.        }
  40.     BInit: TGroupBox;
  41.     CInit: TGroupBox;
  42.     DInit: TGroupBox;
  43.     EInit: TGroupBox;
  44.     FInit: TGroupBox;
  45.     GInit: TGroupBox;
  46.     Hinit: TGroupBox;
  47.     IInit: TGroupBox;
  48.     Jinit: TGroupBox;
  49.     KInit: TGroupBox;
  50.     LInit: TGroupBox;
  51.     MInit: TGroupBox;
  52.     NInit: TGroupBox;
  53.     OInit: TGroupBox;
  54.     PInit: TGroupBox;
  55.     QInit: TGroupBox;
  56.     RInit: TGroupBox;
  57.     SInit: TGroupBox;
  58.     TInit: TGroupBox;
  59.     UInit: TGroupBox;
  60.     VInit: TGroupBox;
  61.     WInit: TGroupBox;
  62.     XInit: TGroupBox;
  63.     YInit: TGroupBox;
  64.     ZInit: TGroupBox;
  65.  
  66.     AValue: TLabel;        { Values displayed on the "INIT" page.    }
  67.     BValue: TLabel;
  68.     CValue: TLabel;
  69.     DValue: TLabel;
  70.     EValue: TLabel;
  71.     FValue: TLabel;
  72.     GValue: TLabel;
  73.     HValue: TLabel;
  74.     IValue: TLabel;
  75.     JValue: TLabel;
  76.     KValue: TLabel;
  77.     LValue: TLabel;
  78.     MValue: TLabel;
  79.     NValue: TLabel;
  80.     OValue: TLabel;
  81.     PValue: TLabel;
  82.     QValue: TLabel;
  83.     RValue: TLabel;
  84.     SValue: TLabel;
  85.     TValue: TLabel;
  86.     UValue: TLabel;
  87.     VValue: TLabel;
  88.     WValue: TLabel;
  89.     XValue: TLabel;
  90.     YValue: TLabel;
  91.     ZValue: TLabel;
  92.  
  93.  
  94.     Exit: TButton;    { Various buttons appearing on the forms.    }
  95.     ExitBtn1: TButton;
  96.     ExitBtn: TButton;
  97.     AboutBtn1: TButton;
  98.     AboutBtn2: TButton;
  99.     AboutBtn3: TButton;
  100.     AddEqnBtn: TButton;
  101.     DeleteBtn: TButton;
  102.     EditBtn: TButton;
  103.     PrintBtn: TButton;
  104.     PrintBtn2: TButton;
  105.     PrintBtn3: TButton;
  106.     PulseBtn: TBitBtn;
  107.  
  108.     PrintDialog: TPrintDialog;
  109.     InstabilityAnnunc: TPanel;
  110.  
  111.     tt30: TPanel;    { Squares in the truth table on the create page    }
  112.     tt31: TPanel;
  113.     tt32: TPanel;
  114.     tt33: TPanel;
  115.     tt00: TPanel;
  116.     tt01: TPanel;
  117.     tt02: TPanel;
  118.     tt03: TPanel;
  119.     tt10: TPanel;
  120.     tt20: TPanel;
  121.     tt11: TPanel;
  122.     tt12: TPanel;
  123.     tt13: TPanel;
  124.     tt21: TPanel;
  125.     tt22: TPanel;
  126.     tt23: TPanel;
  127.  
  128.     ctt00: TPanel;
  129.     ctt10: TPanel;
  130.     ctt20: TPanel;
  131.     ctt30: TPanel;
  132.     ctt01: TPanel;
  133.     ctt02: TPanel;
  134.     ctt03: TPanel;
  135.     ctt11: TPanel;
  136.     ctt12: TPanel;
  137.     ctt13: TPanel;
  138.     ctt21: TPanel;
  139.     ctt22: TPanel;
  140.     ctt23: TPanel;
  141.     ctt31: TPanel;
  142.     ctt32: TPanel;
  143.     ctt33: TPanel;
  144.  
  145.  
  146.     ba00: TLabel;    {Labels on the truth table.            }
  147.     ba01: TLabel;
  148.     ba10: TLabel;
  149.     ba11: TLabel;
  150.     dc00: TLabel;
  151.     DC01: TLabel;
  152.     DC10: TLabel;
  153.     DC11: TLabel;
  154.     dc211: TLabel;
  155.     dc210: TLabel;
  156.     dc201: TLabel;
  157.     dc200: TLabel;
  158.  
  159.     RBrace1: TLabel;
  160.     ClkLbl1: TLabel;
  161.     RBrace2: TLabel;
  162.     ClkLbl2: TLabel;
  163.  
  164.     InitInstrsLbl: TLabel;
  165.     Instrs2: TLabel;
  166.     ExecEqns: TMemo;
  167.  
  168.     procedure COn(Sender: TObject);
  169.     procedure COff(Sender: TObject);
  170.     procedure FormCreate(Sender: TObject);
  171.     procedure AOff(Sender: TObject);
  172.     procedure AOn(Sender: TObject);
  173.     procedure BOff(Sender: TObject);
  174.     procedure BOn(Sender: TObject);
  175.     procedure DOff(Sender: TObject);
  176.     procedure DOn(Sender: TObject);
  177.     procedure ExitBtnClick(Sender: TObject);
  178.     procedure AboutBtn2Click(Sender: TObject);
  179.     procedure InitClick(Sender: TObject);
  180.     procedure AddEqnBtnClick(Sender: TObject);
  181.     procedure ValueClick(Sender: TObject);
  182.     procedure EqnListClick(Sender: TObject);
  183.     procedure EditBtnClick(Sender: TObject);
  184.     procedure EqnListDblClick(Sender: TObject);
  185.     procedure DeleteBtnClick(Sender: TObject);
  186.     procedure PrintBtnClick(Sender: TObject);
  187.     procedure ScreensChange(Sender: TObject; NewTab: Integer;
  188.       var AllowChange: Boolean);
  189.     procedure PulseBtnClick(Sender: TObject);
  190.  
  191.   private
  192.     { Private declarations }
  193.   public
  194.     { Public declarations }
  195.   end;
  196.  
  197.  
  198.  
  199.   { TruthType-    Data type that holds the binary information of a truth    }
  200.   {        table.  NumVars is the number of variables that provide    }
  201.   {        indexes into this truth table.  theVars[0..3] are the    }
  202.   {        single character variable names used in this function.    }
  203.   {        theVars[4] is where the function stores its result.    }
  204.   {        tt[clk,d,c,b,a] is the actual truth table.        }
  205.  
  206.   TruthType = record
  207.           NumVars:integer;
  208.                 theVars:array [0..4] of char;
  209.                 tt:array [0..1,0..1,0..1,0..1,0..1] of integer;
  210.  
  211.             end;
  212. var
  213.   LogicEval: TLogicEval;
  214.  
  215.   { tt is an array of pointers to the panels that make up the squares    }
  216.   { of the truth table on the create page.  It provides a convenient    }
  217.   { way to access those panels using array notation.            }
  218.  
  219.   tt: array [0..1, 0..1, 0..1, 0..1, 0..1] of TPanel;
  220.  
  221.   { TruthTbls holds the truth tables for each of the functions the    }
  222.   { user defines on the Create page.                    }
  223.  
  224.   TruthTbls: array ['A'..'Z'] of TruthType;
  225.  
  226.   { EqnSet holds the set of variables that have been defined and for    }
  227.   { which truth tables exist.                        }
  228.  
  229.   EqnSet: set of char;
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239. implementation
  240.  
  241. {$R *.DFM}
  242.  
  243. uses EqnEntry;
  244.  
  245.  
  246. type
  247.    variables= array ['@'..'['] of integer;
  248.  
  249. var
  250.  
  251.    { Values holds the current values of all the variables in the system    }
  252.    { Values2 is an array of pointers that point at the labels that    }
  253.    { display each of the values on the initialization page.        }
  254.  
  255.    Values:    variables;
  256.    Values2:    array ['@'..'['] of TLabel;
  257.  
  258.  
  259.  
  260.  
  261.  
  262. { FormCreate does all the initialization when the program starts.    }
  263.  
  264. procedure TLogicEval.FormCreate(Sender: TObject);
  265. var i:integer;
  266.     ch:char;
  267.  
  268. begin
  269.  
  270.  
  271.      { Label all the variables on the EXECUTE page.  Also, set their    }
  272.      { values all to zero.                        }
  273.  
  274.      for i := 1 to 26 do
  275.      begin
  276.  
  277.          ExecVariables.Cells[i,0] := chr(ord('@') + i);
  278.          ExecVariables.Cells[i,1] := '0';
  279.  
  280.      end;
  281.      ExecVariables.Cells[0,0] := '#';
  282.      ExecVariables.Cells[0,1] := '0';
  283.  
  284.      { Initialize all the variable values to zero.            }
  285.  
  286.      for ch := '@' to '[' do Values[ch] := 0;
  287.  
  288.      { At this point there are no equations defined.  Note that here.    }
  289.  
  290.      EqnSet := [];
  291.  
  292.      { Initialize the array of Value pointers so they point at the    }
  293.      { value labels on the initialization page.                }
  294.  
  295.      Values2['A'] := AValue;
  296.      Values2['B'] := BValue;
  297.      Values2['C'] := CValue;
  298.      Values2['D'] := DValue;
  299.      Values2['E'] := EValue;
  300.      Values2['F'] := FValue;
  301.      Values2['G'] := GValue;
  302.      Values2['H'] := HValue;
  303.      Values2['I'] := IValue;
  304.      Values2['J'] := JValue;
  305.      Values2['K'] := KValue;
  306.      Values2['L'] := LValue;
  307.      Values2['M'] := MValue;
  308.      Values2['N'] := NValue;
  309.      Values2['O'] := OValue;
  310.      Values2['P'] := PValue;
  311.      Values2['Q'] := QValue;
  312.      Values2['R'] := RValue;
  313.      Values2['S'] := SValue;
  314.      Values2['T'] := TValue;
  315.      Values2['U'] := UValue;
  316.      Values2['V'] := VValue;
  317.      Values2['W'] := WValue;
  318.      Values2['X'] := XValue;
  319.      Values2['Y'] := YValue;
  320.      Values2['Z'] := ZValue;
  321.  
  322.  
  323.      { Initialize the tt array so that each element points at the    }
  324.      { appropriate square on the truth table on the CREATE page.    }
  325.  
  326.      tt[0, 0,0,0,0]:= tt00;
  327.      tt[0, 0,0,0,1]:= tt01;
  328.      tt[0, 0,0,1,0]:= tt02;
  329.      tt[0, 0,0,1,1]:= tt03;
  330.  
  331.      tt[0, 0,1,0,0]:= tt10;
  332.      tt[0, 0,1,0,1]:= tt11;
  333.      tt[0, 0,1,1,0]:= tt12;
  334.      tt[0, 0,1,1,1]:= tt13;
  335.  
  336.      tt[0, 1,0,0,0]:= tt20;
  337.      tt[0, 1,0,0,1]:= tt21;
  338.      tt[0, 1,0,1,0]:= tt22;
  339.      tt[0, 1,0,1,1]:= tt23;
  340.  
  341.      tt[0, 1,1,0,0]:= tt30;
  342.      tt[0, 1,1,0,1]:= tt31;
  343.      tt[0, 1,1,1,0]:= tt32;
  344.      tt[0, 1,1,1,1]:= tt33;
  345.  
  346.  
  347.      tt[1, 0,0,0,0]:= ctt00;
  348.      tt[1, 0,0,0,1]:= ctt01;
  349.      tt[1, 0,0,1,0]:= ctt02;
  350.      tt[1, 0,0,1,1]:= ctt03;
  351.  
  352.      tt[1, 0,1,0,0]:= ctt10;
  353.      tt[1, 0,1,0,1]:= ctt11;
  354.      tt[1, 0,1,1,0]:= ctt12;
  355.      tt[1, 0,1,1,1]:= ctt13;
  356.  
  357.      tt[1, 1,0,0,0]:= ctt20;
  358.      tt[1, 1,0,0,1]:= ctt21;
  359.      tt[1, 1,0,1,0]:= ctt22;
  360.      tt[1, 1,0,1,1]:= ctt23;
  361.  
  362.      tt[1, 1,1,0,0]:= ctt30;
  363.      tt[1, 1,1,0,1]:= ctt31;
  364.      tt[1, 1,1,1,0]:= ctt32;
  365.      tt[1, 1,1,1,1]:= ctt33;
  366.  
  367.      { Initialize the default equation for the equation editor.        }
  368.  
  369.      LastEqn := 'F=0';
  370.  
  371.      { Make the CREATE page show up on the form when we start.        }
  372.  
  373.      Screens.ActivePage := 'Create';
  374.  
  375. end;
  376.  
  377.  
  378.  
  379. { The following procedure stores "Value" into the variable specified by    }
  380. { "vName".  It also updates the variable display and any necessary LEDs    }
  381. { on the EXECUTE page.                            }
  382.  
  383. procedure SetVar(vName:char; Value:integer);
  384. begin
  385.  
  386.   with LogicEval do begin
  387.  
  388.      { Convert "#" to "@" so we can use a compact array ("@" appears    }
  389.      { just before "A" in the ASCII character set, "#" is some distance    }
  390.      { away from the alphabetic characters).                }
  391.  
  392.      if (vName = '#') then vName := '@';
  393.  
  394.      { Update the value in the Values matrix and the label on the init-    }
  395.      { ialization page.                            }
  396.  
  397.      Values [vName] := Value;
  398.      Values2[vName].Caption := chr(Value+ord('0'));
  399.  
  400.      { Update the value on the EXECUTE page.                }
  401.  
  402.      ExecVariables.Cells[ord(vName)-ord('@'),1] :=
  403.            chr(ord('0') + Value);
  404.  
  405.      { If this variable is E..K, then update the corresponding segment    }
  406.      { on the seven-segment display.                    }
  407.  
  408.      if (vName = 'E') then
  409.         if (Value = 1) then E.Brush.Color := clRed
  410.         else E.Brush.Color := clSilver;
  411.  
  412.      if (vName = 'F') then
  413.         if (Value = 1) then F.Brush.Color := clRed
  414.         else F.Brush.Color := clSilver;
  415.  
  416.      if (vName = 'G') then
  417.         if (Value = 1) then G.Brush.Color := clRed
  418.         else G.Brush.Color := clSilver;
  419.  
  420.      if (vName = 'H') then
  421.         if (Value = 1) then H.Brush.Color := clRed
  422.         else H.Brush.Color := clSilver;
  423.  
  424.      if (vName = 'I') then
  425.         if (Value = 1) then I.Brush.Color := clRed
  426.         else I.Brush.Color := clSilver;
  427.  
  428.      if (vName = 'J') then
  429.         if (Value = 1) then J.Brush.Color := clRed
  430.         else J.Brush.Color := clSilver;
  431.  
  432.      if (vName = 'K') then
  433.         if (Value = 1) then K.Brush.Color := clRed
  434.         else K.Brush.Color := clSilver;
  435.  
  436.  
  437.      { If this variable is W..Z, then update the corresponding LED.    }
  438.  
  439.      if (vName = 'W') then
  440.         if (Value = 1) then W.Brush.Color := clRed
  441.         else W.Brush.Color := clWhite;
  442.  
  443.      if (vName = 'X') then
  444.         if (Value = 1) then X.Brush.Color := clRed
  445.         else X.Brush.Color := clWhite;
  446.  
  447.      if (vName = 'Y') then
  448.         if (Value = 1) then Y.Brush.Color := clRed
  449.         else Y.Brush.Color := clWhite;
  450.  
  451.      if (vName = 'Z') then
  452.         if (Value = 1) then Z.Brush.Color := clRed
  453.         else Z.Brush.Color := clWhite;
  454.  
  455.   end;
  456. end;
  457.  
  458.  
  459.  
  460.  
  461. { The following function evaluates the system of logic equations.    }
  462.  
  463. procedure Eval;
  464. var
  465.     i        :integer;
  466.     funcCount    :integer;
  467.     CurVar    :char;
  468.     prevVals    :variables;
  469.  
  470.  
  471.  
  472.  { CmpVars-    Compares two arrays of type "variables" and returns    }
  473.  {        true if they are equal.                    }
  474.  
  475.  function CmpVars(var v1, v2:Variables):boolean;
  476.  assembler;
  477.  asm
  478.             push    ds
  479.         les    di, v2
  480.                 lds    si, v1
  481.                 mov    cx, 27
  482.                 repe cmpsw
  483.                 mov    ax, 1
  484.                 cmp    cx, 0
  485.                 je    @@0
  486.                 mov    ax, 0
  487.         @@0:
  488.                 pop    ds
  489.  end;
  490.  
  491.  
  492.  { EvalOnce-    Evaluates all the active logic equations one time each.    }
  493.  {        This function returns the number of active logic equa-    }
  494.  {        tions in the system.  Note that for a complete logic     }
  495.  {        system evaluation, that is, to allow values to propogate}
  496.  {        throughout the system of equations, you must evaluate    }
  497.  {        the set of equations at least n times where "n" is the    }
  498.  {        number of logic equations in the system.        }
  499.  
  500.  function EvalOnce:integer;
  501.  var
  502.      funcName:    char;
  503.      val:    integer;
  504.  
  505.  begin
  506.  
  507.   Result := 0;
  508.  
  509.   { The following loop, in conjunction with the IF stmt, executes once    }
  510.   { for each active equation in the system.                }
  511.  
  512.   for funcName := 'A' to 'Z' do
  513.     if funcName in EqnSet then
  514.     begin
  515.  
  516.       { The following case statement handles the case where the current    }
  517.       { equation has zero, one, two, three, or four variables.  It com-    }
  518.       { putes the new value by using a lookup based on the current vari-}
  519.       { able values.                            }
  520.  
  521.       case TruthTbls[funcName].NumVars of
  522.       0: val := TruthTbls[funcName].tt[Values['@'],0,0,0,0];
  523.       1: val := TruthTbls[funcName].tt[Values['@'],0,0,0,
  524.                             Values[TruthTbls[funcName].theVars[0]]];
  525.       2: val := TruthTbls[funcName].tt[Values['@'],0,0,
  526.                             Values[TruthTbls[funcName].theVars[1]],
  527.                             Values[TruthTbls[funcName].theVars[0]]];
  528.       3: val := TruthTbls[funcName].tt[Values['@'],0,
  529.                             Values[TruthTbls[funcName].theVars[2]],
  530.                             Values[TruthTbls[funcName].theVars[1]],
  531.                             Values[TruthTbls[funcName].theVars[0]]];
  532.       4: val := TruthTbls[funcName].tt[Values['@'],
  533.                             Values[TruthTbls[funcName].theVars[3]],
  534.                             Values[TruthTbls[funcName].theVars[2]],
  535.                             Values[TruthTbls[funcName].theVars[1]],
  536.                             Values[TruthTbls[funcName].theVars[0]]];
  537.       end;
  538.  
  539.       { Update the current function's variable with the value obtained above. }
  540.  
  541.       Values[funcName] := val;
  542.  
  543.       { Count the number of functions we've processed down here. }
  544.  
  545.       inc(Result);
  546.  
  547.     end;
  548.  end;
  549.  
  550.  
  551.  
  552.  
  553. begin {Eval}
  554.  
  555.     { Call EvalOnce to obtain the number of functions in the system.    }
  556.     { Bump this value by one since we've got the clock variable to worry}
  557.     { about, as well.                            }
  558.  
  559.     funcCount := EvalOnce + 1;
  560.  
  561.  
  562.     { Evaluate the system of equations "funcCount" times.  This gives    }
  563.     { us a total of "n+2" evaluations where "n" is the number of funcs.    }
  564.     { The first extra execution is for the clock variable, the second    }
  565.     { extra execution provides a safety margin.                }
  566.  
  567.     for i := 1 to funcCount do EvalOnce;
  568.  
  569.     { Now let's check for instability.  Save the current set of values    }
  570.     { and execute the set of equations one more time.  If the system is    }
  571.     { stable, we should obtain the exact same set of values.  If the    }
  572.     { system is unstable, they will differ.                }
  573.  
  574.     prevVals := Values;
  575.     EvalOnce;
  576.  
  577.     { If the system is unstable, turn on the Instability annunciator.    }
  578.     { If the system is stable, turn the annunciator off.        }
  579.  
  580.     if CmpVars(prevVals,Values) then
  581.          LogicEval.InstabilityAnnunc.Color := clGray
  582.     else LogicEval.InstabilityAnnunc.Color := clRed;
  583.  
  584.     { Throughout the operations above, EvalOnce stored results directly    }
  585.     { into the Values array rather than (correctly) calling SetVar. The    }
  586.     { reason is because EvalOnce would call SetVar a tremendous number    }
  587.     { of times and SetVar is rather slow.  Therefore, we need to call    }
  588.     { SetVar once for each variable to ensure that all LEDs, display    }
  589.     { values, etc., are properly updated.                }
  590.  
  591.     for CurVar := '@' to 'Z' do
  592.         SetVar(CurVar,Values[CurVar]);
  593.  
  594. end;
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601. { The following procedures handle button toggle events.  Whenever the    }
  602. { user toggles one of the four input values (A..D) the following pro-    }
  603. { cedures adjust the values of the corresponding variables and then    }
  604. { they evaluate the system of logic equations.                }
  605.  
  606. procedure TLogicEval.AOff(Sender: TObject);
  607. begin
  608.      SetVar('A',0);
  609.      Eval;
  610. end;
  611.  
  612. procedure TLogicEval.AOn(Sender: TObject);
  613. begin
  614.      SetVar('A',1);
  615.      Eval;
  616. end;
  617.  
  618. procedure TLogicEval.BOff(Sender: TObject);
  619. begin
  620.      SetVar('B',0);
  621.      Eval;
  622. end;
  623.  
  624. procedure TLogicEval.BOn(Sender: TObject);
  625. begin
  626.      SetVar('B',1);
  627.      Eval;
  628. end;
  629.  
  630. procedure TLogicEval.COn(Sender: TObject);
  631. begin
  632.      SetVar('C',1);
  633.      Eval;
  634. end;
  635.  
  636. procedure TLogicEval.COff(Sender: TObject);
  637. begin
  638.      SetVar('C',0);
  639.      Eval;
  640. end;
  641.  
  642. procedure TLogicEval.DOff(Sender: TObject);
  643. begin
  644.      SetVar('D',0);
  645.      Eval;
  646. end;
  647.  
  648. procedure TLogicEval.DOn(Sender: TObject);
  649. begin
  650.      SetVar('D',1);
  651.      Eval;
  652. end;
  653.  
  654.  
  655. { If the user hits the "Pulse" button, set the clock to zero and eval-    }
  656. { uate the system, set the clock to one and evaluate the system, and     }
  657. { then set the clock back to zero and reevaluate the equations.        }
  658.  
  659. procedure TLogicEval.PulseBtnClick(Sender: TObject);
  660. begin
  661.  
  662.     Values['@'] := 0;
  663.     Eval;
  664.     Values['@'] := 1;
  665.     Eval;
  666.     Values['@'] := 0;
  667.     Eval;
  668.  
  669. end;
  670.  
  671.  
  672. { The system calls the following functions whenever the user clicks on    }
  673. { one of the buttons on the initialization page.  This code figures    }
  674. { out which button was pressed and toggles its value.  The InitClick    }
  675. { procedure runs whenever the user clicks on the panel (button), the    }
  676. { ValueClick procedure runs if the users clicks on the actual value    }
  677. { within the panel.                            }
  678.  
  679. procedure TLogicEval.InitClick(Sender: TObject);
  680. var name:char;
  681. begin
  682.  
  683.    {The first character of the Box's Caption is the variable's name.    }
  684.  
  685.    name := (Sender as TGroupBox).Caption[1];
  686.  
  687.    { Fetch that variable's value, invert it, and write it back.        }
  688.  
  689.    SetVar(Name, Values[name] xor 1);
  690.  
  691. end;
  692.  
  693. procedure TLogicEval.ValueClick(Sender: TObject);
  694. var name:char;
  695. begin
  696.  
  697.    name := ((Sender as TLabel).Parent as TGroupBox).Caption[1];
  698.    SetVar(Name, Values[name] xor 1);
  699.  
  700. end;
  701.  
  702.  
  703.  
  704.  
  705. { If the user presses the "ADD" button, bring up the equation dialog    }
  706. { box and let them add a new equation to the system.            }
  707.  
  708. procedure TLogicEval.AddEqnBtnClick(Sender: TObject);
  709. begin
  710.  
  711.      EqnDlg.InputEqn.SelectAll;    {Select equation inside dialog box.    }
  712.      EqnDlg.Show;        {Open the equation dialog box.        }
  713.  
  714. end;
  715.  
  716.  
  717. { If the user clicks on an equation in the equation list box, update    }
  718. { the truth table on the create page to display the truth table for    }
  719. { the selected equation.                        }
  720.  
  721. procedure TLogicEval.EqnListClick(Sender: TObject);
  722. var ch:char;
  723. begin
  724.  
  725.     if (EqnList.ItemIndex <> -1) then {Make sure there is a selection.    }
  726.     begin
  727.  
  728.         ch := EqnList.Items[EqnList.ItemIndex][1]; {Get function name.    }
  729.     DrawTruths(TruthTbls[ch]); {Draw that function's truth table.    }
  730.  
  731.     end;
  732.  
  733. end;
  734.  
  735.  
  736. { If the user double-clicks on an equation in the equation list box,    }
  737. { then bring up the equation editor dialog box and let them edit this    }
  738. { equation.                                }
  739.  
  740. procedure TLogicEval.EqnListDblClick(Sender: TObject);
  741. begin
  742.  
  743.     if (EqnList.ItemIndex <> -1) then {Is there a selection?    }
  744.         begin
  745.  
  746.             { Grab the equation the user just selected and make it the    }
  747.             { default equation in the equation dialog box.        }
  748.  
  749.             EqnDlg.InputEqn.Text := EqnList.Items[EqnList.ItemIndex];
  750.  
  751.             { Select the equation.                    }
  752.  
  753.             EqnDlg.InputEqn.SelectAll;
  754.  
  755.             { Bring up the equation editor dialog box.            }
  756.  
  757.             EqnDlg.Show;
  758.  
  759.         end;
  760. end;
  761.  
  762.  
  763. { If the user presses the edit button and there is a selected equation    }
  764. { in the equation list box, open up the equation editor dialog box and    }
  765. { let the user edit that equation.                    }
  766.  
  767. procedure TLogicEval.EditBtnClick(Sender: TObject);
  768. begin
  769.  
  770.     { If there is a selected equation, copy it to the default    }
  771.         { equation in the equation editor dialog box.  If there is no    }
  772.         { such equation available, just use the current default equa-    }
  773.         { tion when it opens the equation editor dialog box.        }
  774.  
  775.     if (EqnList.Items.Count <> 0) then   {Are there any equations?    }
  776.            if (EqnList.ItemIndex <> -1) then {Is an equation selected?    }
  777.                EqnDlg.InputEqn.Text := EqnList.Items[EqnList.ItemIndex];
  778.  
  779.         { Select the equation and open up the dialog box.        }
  780.  
  781.         EqnDlg.InputEqn.SelectAll;
  782.         EqnDlg.Show;
  783.  
  784. end;
  785.  
  786.  
  787. { If the user has selected and equation and presses the delete button,    }
  788. { the following procedure deletes that equation from the list and re-    }
  789. { moves that function definition from the EqnSet.            }
  790.  
  791. procedure TLogicEval.DeleteBtnClick(Sender: TObject);
  792. var     ch:    char;
  793.     dummy:    TruthType;
  794. begin
  795.  
  796.     if (EqnList.ItemIndex <> -1) then {Is there an equation selected? }
  797.         begin
  798.  
  799.             { Make sure the user really wants to do this. }
  800.  
  801.             if MessageDlg('Okay to delete ' +
  802.                     EqnList.Items[EqnList.ItemIndex] + '?',
  803.                       mtWarning, [mbYes, mbNo], 0) = mrYes then
  804.             begin
  805.  
  806.                 { Remove the equation from our equation set.        }
  807.  
  808.             EqnSet := EqnSet - [EqnList.Items[EqnList.ItemIndex][1]];
  809.  
  810.                 { Remove the equation from the list of equations.    }
  811.  
  812.                 EqnList.Items.Delete(EqnList.ItemIndex);
  813.  
  814.                 { Since there is no longer a selected equation in the    }
  815.                 { equation list, clear the truth tables.        }
  816.  
  817.                 dummy.NumVars := 0;
  818.                 DrawTruths(dummy);
  819.  
  820.             end;
  821.  
  822.         end;
  823. end;
  824.  
  825.  
  826. { Miscellaneous procedures to handle the PRINT, ABOUT, and EXIT buttons    }
  827. { found on each page of the form.                    }
  828.  
  829. procedure TLogicEval.PrintBtnClick(Sender: TObject);
  830. begin
  831.  
  832.     if (PrintDialog.Execute) then
  833.         begin
  834.  
  835.             LogicEval.Print;
  836.  
  837.         end;
  838.  
  839. end;
  840.  
  841. procedure TLogicEval.ExitBtnClick(Sender: TObject);
  842. begin
  843.      Halt;
  844. end;
  845.  
  846. procedure TLogicEval.AboutBtn2Click(Sender: TObject);
  847. begin
  848.      AboutBox.Show;
  849. end;
  850.  
  851.  
  852. procedure TLogicEval.ScreensChange(    Sender: TObject;
  853.                     NewTab: Integer;
  854.                       var AllowChange: Boolean);
  855. var
  856.     i:    integer;
  857. begin
  858.  
  859.     AllowChange := true;
  860.         if NewTab = 2 then
  861.         begin
  862.  
  863.             ExecEqns.Clear;
  864.             for i := 0 to EqnList.Items.Count - 1 do
  865.                 ExecEqns.Lines.Add(EqnList.Items[i]);
  866.  
  867.             Eval;
  868.  
  869.         end;
  870. end;
  871.  
  872. end.
  873.